use sea_orm_migration::prelude::*;

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
    async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        manager
            .create_table(
                Table::create()
                    .table(SysMenu::Table)
                    .if_not_exists()
                    .col(
                        ColumnDef::new(SysMenu::Id)
                            .big_integer()
                            .not_null()
                            .auto_increment()
                            .primary_key(),
                    )
                    .col(ColumnDef::new(SysMenu::Pid).big_integer())
                    .col(ColumnDef::new(SysMenu::Name).string().string_len(100).not_null())
                    .col(ColumnDef::new(SysMenu::Url).string().string_len(100))
                    .col(ColumnDef::new(SysMenu::Authority).string().string_len(100))
                    .col(ColumnDef::new(SysMenu::Type).integer())
                    .col(ColumnDef::new(SysMenu::OpenStyle).integer())
                    .col(ColumnDef::new(SysMenu::Icon).string().string_len(100))
                    .col(ColumnDef::new(SysMenu::Sort).integer())
                    .col(ColumnDef::new(SysMenu::IsShow).integer().default(0))
                    .col(ColumnDef::new(SysMenu::Creator).big_integer())
                    .col(ColumnDef::new(SysMenu::CreatedAt).timestamp_with_time_zone().not_null())
                    .col(ColumnDef::new(SysMenu::Updater).big_integer())
                    .col(ColumnDef::new(SysMenu::UpdatedAt).timestamp_with_time_zone())
                    .col(ColumnDef::new(SysMenu::Version).integer().default(0))
                    .col(ColumnDef::new(SysMenu::Deleted).integer().default(0))
                    .to_owned(),
            )
            .await?;

        // 插入初始菜单数据
        insert_initial_menus(manager).await
    }

    async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
        manager
            .drop_table(Table::drop().table(SysMenu::Table).to_owned())
            .await
    }
}

// 👇 提取到独立函数，避免 up() 过长 
async fn insert_initial_menus(manager: &SchemaManager<'_>) -> Result<(), DbErr> {
    let now = Expr::current_timestamp(); // 数据库函数 now()

    let menu_data = vec![
        // (id, pid, name, url, authority, type_, open_style, icon, sort, is_show, creator, updater)
        (1,   None, "系统设置",         None, None,                   0, 0, "icon-setting",           1, 0, 10000, 10000),
        (2,   Some(1), "菜单管理",      Some("sys/menu/index"), None, 0, 0, "icon-menu",              0, 0, 10000, 10000),
        (3,   Some(2), "查看",          Some(""), Some("sys:menu:list"), 1, 0, "",                     0, 0, 10000, 10000),
        (4,   Some(2), "新增",          Some(""), Some("sys:menu:save"), 1, 0, "",                     1, 0, 10000, 10000),
        (5,   Some(2), "修改",          Some(""), Some("sys:menu:update,sys:menu:info"), 1, 0, "",     2, 0, 10000, 10000),
        (6,   Some(2), "删除",          Some(""), Some("sys:menu:delete"), 1, 0, "",                   3, 0, 10000, 10000),
        (7,   Some(1), "数据字典",      Some("sys/dict/type"), Some(""), 0, 0, "icon-insertrowabove",   1, 0, 10000, 10000),
        (8,   Some(7), "查询",          Some(""), Some("sys:dict:page"), 1, 0, "",                    0, 0, 10000, 10000),
        (9,   Some(7), "新增",          Some(""), Some("sys:dict:save"), 1, 0, "",                    2, 0, 10000, 10000),
        (10,  Some(7), "修改",          Some(""), Some("sys:dict:update,sys:dict:info"), 1, 0, "",    1, 0, 10000, 10000),
        (11,  Some(7), "删除",          Some(""), Some("sys:dict:delete"), 1, 0, "",                  3, 0, 10000, 10000),
        (12,  None,    "权限管理",      Some(""), Some(""),               0, 0, "icon-safetycertificate", 0, 0, 10000, 10000),
        (13,  Some(12),"岗位管理",      Some("sys/post/index"), Some(""), 0, 0, "icon-solution",       2, 0, 10000, 10000),
        (14,  Some(13),"查询",          Some(""), Some("sys:post:page"), 1, 0, "",                    0, 0, 10000, 10000),
        (15,  Some(13),"新增",          Some(""), Some("sys:post:save"), 1, 0, "",                    1, 0, 10000, 10000),
        (16,  Some(13),"修改",          Some(""), Some("sys:post:update,sys:post:info"), 1, 0, "",    2, 0, 10000, 10000),
        (17,  Some(13),"删除",          Some(""), Some("sys:post:delete"), 1, 0, "",                  3, 0, 10000, 10000),
        (18,  Some(12),"机构管理",      Some("sys/org/index"), Some(""), 0, 0, "icon-cluster",         1, 0, 10000, 10000),
        (19,  Some(18),"查询",          Some(""), Some("sys:org:list"), 1, 0, "",                     0, 0, 10000, 10000),
        (20,  Some(18),"新增",          Some(""), Some("sys:org:save"), 1, 0, "",                     1, 0, 10000, 10000),
        (21,  Some(18),"修改",          Some(""), Some("sys:org:update,sys:org:info"), 1, 0, "",      2, 0, 10000, 10000),
        (22,  Some(18),"删除",          Some(""), Some("sys:org:delete"), 1, 0, "",                   3, 0, 10000, 10000),
        (23,  Some(12),"角色管理",      Some("sys/role/index"), Some(""), 0, 0, "icon-team",           3, 0, 10000, 10000),
        (24,  Some(23),"查询",          Some(""), Some("sys:role:page"), 1, 0, "",                    0, 0, 10000, 10000),
        (25,  Some(23),"新增",          Some(""), Some("sys:role:save,sys:role:menu,sys:org:list"), 1, 0, "", 1, 0, 10000, 10000),
        (26,  Some(23),"修改",          Some(""), Some("sys:role:update,sys:role:info,sys:role:menu,sys:org:list,sys:user:page"), 1, 0, "", 2, 0, 10000, 10000),
        (27,  Some(23),"删除",          Some(""), Some("sys:role:delete"), 1, 0, "",                  3, 0, 10000, 10000),
        (28,  Some(12),"用户管理",      Some("sys/user/index"), Some(""), 0, 0, "icon-user",           0, 0, 10000, 10000),
        (29,  Some(28),"查询",          Some(""), Some("sys:user:page"), 1, 0, "",                    0, 0, 10000, 10000),
        (30,  Some(28),"新增",          Some(""), Some("sys:user:save,sys:role:list"), 1, 0, "",      1, 0, 10000, 10000),
        (31,  Some(28),"修改",          Some(""), Some("sys:user:update,sys:user:info,sys:role:list"), 1, 0, "", 2, 0, 10000, 10000),
        (32,  Some(28),"删除",          Some(""), Some("sys:user:delete"), 1, 0, "",                  3, 0, 10000, 10000),
        (33,  None,    "应用管理",      Some(""), Some(""),               0, 0, "icon-appstore",       2, 0, 10000, 10000),
        (34,  None,    "日志管理",      Some(""), Some(""),               0, 0, "icon-filedone",       3, 0, 10000, 10000),
        (35,  Some(34),"登录日志",      Some("sys/log/login"), Some("sys:log:login"), 0, 0, "icon-solution", 0, 0, 10000, 10000),
        (36,  Some(28),"导入",          Some(""), Some("sys:user:import"), 1, 0, "",                  5, 0, 10000, 10000),
        (37,  Some(28),"导出",          Some(""), Some("sys:user:export"), 1, 0, "",                  6, 0, 10000, 10000),
        (38,  Some(1), "参数管理",      Some("sys/params/index"), Some("sys:params:all"), 0, 0, "icon-filedone", 2, 0, 10000, 10000),
        (39,  Some(1), "接口文档",      Some("{{apiUrl}}/doc.html"), None, 0, 1, "icon-file-text-fill", 10, 0, 10000, 10000),
        (40,  Some(34),"操作日志",      Some("sys/log/operate"), Some("sys:operate:all"), 0, 0, "icon-file-text", 1, 0, 10000, 10000),
        (41,  Some(1), "系统配置",      Some("sys/config/index"), None, 0, 0, "icon-safetycertificate", 4, 0, 10000, 10000),
        (42,  Some(41),"短信配置",      Some(""), Some("sys:sms:config"), 1, 0, "",                  0, 0, 10000, 10000),
        (43,  Some(41),"邮件配置",      Some(""), Some("sys:mail:config"), 1, 0, "",                  1, 0, 10000, 10000),
        (44,  Some(41),"第三方登录",    Some(""), Some("sys:third:config"), 1, 0, "",                 2, 0, 10000, 10000),
        (45,  None,    "基础工具",      Some(""), Some(""),               0, 0, "icon-wrench-fill",    5, 0, 10000, 10000),
        (46,  Some(45),"短信发送",      Some("sys/tool/sms/index"), Some("sys:sms:log"), 0, 0, "icon-message", 1, 0, 10000, 10000),
        (47,  Some(45),"邮件发送",      Some("sys/tool/mail/index"), Some("sys:mail:log"), 0, 0, "icon-mail", 2, 0, 10000, 10000),
        (48,  Some(45),"附件管理",      Some("sys/attachment/index"), None, 0, 0, "icon-folder-fill", 3, 0, 10000, 10000),
        (49,  Some(48),"查看",          Some(""), Some("sys:attachment:page"), 1, 0, "",             0, 0, 10000, 10000),
        (50,  Some(48),"上传",          Some(""), Some("sys:attachment:save"), 1, 0, "",             1, 0, 10000, 10000),
        (51,  Some(48),"删除",          Some(""), Some("sys:attachment:delete"), 1, 0, "",           1, 0, 10000, 10000),
        (52,  None,    "企业版",        Some("https://geoinfo.net/price"), None, 0, 1, "icon-safetycertificate", 10, 0, 10000, 10000),
    ];

    for data in menu_data {
        let insert = Query::insert()
            .into_table(SysMenu::Table)
            .columns([
                SysMenu::Id,
                SysMenu::Pid,
                SysMenu::Name,
                SysMenu::Url,
                SysMenu::Authority,
                SysMenu::Type,
                SysMenu::OpenStyle,
                SysMenu::Icon,
                SysMenu::Sort,
                SysMenu::IsShow,
                SysMenu::Creator,
                SysMenu::CreatedAt,
                SysMenu::Updater,
                SysMenu::UpdatedAt,
                SysMenu::Version,
                SysMenu::Deleted,
            ])
            .values([
                data.0.into(),                             // id
                data.1.map(Into::into).unwrap_or(Value::Int(None).into() ), // pid
                data.2.into(),                             // name
                data.3.map(Into::into).unwrap_or(Value::String(None).into()), // url
                data.4.map(Into::into).unwrap_or(Value::String(None).into()), // authority
                data.5.into(),                             // type
                data.6.into(),                             // open_style
                data.7.into(),                             // icon
                data.8.into(),                             // sort
                data.9.into(),                             // is_show
                data.10.into(),                            // creator
                now.clone().into(),                        // create_time
                data.11.into(),                            // updater
                now.clone().into(),                        // update_time
                0i32.into(),                               // version
                0i32.into(),                               // deleted
            ])
            .unwrap().to_owned();
          manager.exec_stmt(insert).await?;
    }

    Ok(())
}

#[derive(DeriveIden)]
enum SysMenu {
    Table,
    Id,
    Pid,
    Name,
    Url,
    Authority,
    Type,
    OpenStyle,
    Icon,
    Sort,
    IsShow,
    Creator,
    CreatedAt,
    Updater,
    UpdatedAt,
    Version,
    Deleted,
}